
import { AxiosRequestConfig } from 'axios'
import axios from 'axios'
import db from '../localstorage'
import qs from 'qs'
import { message } from 'antd'

interface ObjectFunction extends Function {
  [value: string]: any
}

interface BaseQuery {
  url: string
  params?: Record<string, any>
  baseURL?: string
  responseType?: string
  timeout?: number
  headers?: {
    Authorization?: string
    'Content-Type'?: 'application/x-www-form-urlencoded' | 'application/json'
  }
}

interface GetQuery extends BaseQuery {
  method: 'GET' | 'DELETE'
  data?: Record<string, any>
}

interface PostQuery extends BaseQuery {
  method: 'POST' | 'PUT'
  data?: Record<string, any> | string
}

export type Query = GetQuery | PostQuery

const invalid = function (msg: string) {
  message.error(msg)
  db.clear()
  window.location.href = '/#/login'
}

async function handleSuccess({ data }: any) {
  const { msg, code } = data
  if (code === 200) {
    return data
  } else if (/^401$/.test(code)) {
    throw invalid(msg)
  } else {
    message.error(msg)
    throw null
  }
}

async function handleError(error: any) {
  if (error) {
    const { code } = error
    if (code === 'ECONNABORTED') {
      message.error('请求超时')
    }
  }
  throw null
}

const $http = async function (query: Query, auth = true): Promise<any> {

  const { method, headers = {} } = query;

  const token = db.get('token')
  if (auth) {
    headers.Authorization = `Bearer ${token}`
  }

  if (method === 'GET' || method === 'DELETE') {
    query.params = {
      ...query.params,
      ...query.data
    }
  } else {
    if (headers['Content-Type'] === 'application/x-www-form-urlencoded') {
      query.data = qs.stringify(query.data)
    } else {
      headers['Content-Type'] = 'application/json'
    }
  }

  return axios(<AxiosRequestConfig>{
    baseURL: '/api',
    timeout: 30000,
    ...query,
    headers
  })
    .then(handleSuccess)
    .catch(handleError)
}

export default $http as ObjectFunction
